﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/* 
  *  软件日志存放与管理
  *  作用：主要用来存放和整理软件日志内容
  *  创建时间：2019/07/06 wj
  *  修改时间：2019/08/29 wj
  */
namespace Common.Service.RecordLog
{
    public class RecordManager
    {
        /**
          * \brief 创建各设备类的存储字典
          * 
          * \param[in] string 设备类型，对应Record中的summary
          */
        private Dictionary<string, string> MainRecordDic = new Dictionary<string, string>()
        {
            { "01", "模型载入" },      { "02", "场景缺失" },       

            { "11", "文件写入" },      { "12", "文件读取" },       { "13", "文件路径" },    

            { "21", "http连接失败" },             { "22", "http发送失败" },             { "23", "http接收失败" },          
            { "24", "网络访问异常" }, 

            { "31", "数据配置模式：基本参数导入" },      { "32", "数据配置模式：模型路径导入" },      
            { "33", "数据配置模式：DH参数配置" },        { "34", "数据配置模式：偏置参数导入" },        
            { "35", "数据配置模式：基本参数导入" },  

            { "41", "模型控制模式：模型选择" },                 { "42", "模型控制模式：关节模式控制" },   
            { "43", "模型控制模式：执行器模式控制" },      { "44", "模型控制模式：模型选择" },      

            { "F1", "自研数据检测算法" },      { "F2", "自研检测算法" },          { "F3", "自研智能生成算法" },          
            { "F4", "自研CRC算法" },              { "F5", "自研运动学算法" },      { "F6", "自研速度算法" },       
            { "F7", "自研轨迹规划算法"},       { "F8", "自研动力学算法" },
        };

        // 错误消息订阅
        public static Action<RecordType, string, string> AddError;

        // 用于存放日志单元
        public static Records systemLogRecords = new Records();

        /**
           * \brief 将log数据汇总，进而得出汇总信息
           * 
           * \param[in] recordsList 日志数据列表
           */
        public static string AnalysisLogData(List<Record> recordList)
        {
            int cout = 0;
            int warnNum = 0;
            int errorNum = 0;
            //设置打开文件的格式
            foreach (var w in recordList)
            {
                if (w.type == RecordType.Warn)
                {
                    warnNum++;
                }
                else if (w.type == RecordType.Error)
                {
                    errorNum++;
                }
                else
                {
                    cout++;
                }
            }
            //返回指定信息
            return string.Format("共{0}条. 其中：警告{1}条；错误{2}条", warnNum + errorNum + cout, warnNum, errorNum);
        }

        /** 
           * \brief 错误信息发送功能 
           *
           * \param[in] info 消息类型
           * \param[in] message 消息内容
           * \param[in] tip 消息附录
           */
        public static void SendErrorLog(RecordType type, string message, string tip)
        {
            if (!String.IsNullOrWhiteSpace(message))
            {
            Record record = new Record() { recordID = systemLogRecords.recordList.Count, type = type, message = message, tips = tip };
            systemLogRecords.recordList.Add(record);
            // 清除冗余清空消息 
            systemLogRecords.RemoveRecordData();
            // 订阅函数响应
            AddError(type, message, tip);
            }
        }

        /** 
           * \brief 日志信息清空功能 
           */
        public static void ClearLogRecord()
        {
            systemLogRecords.recordList.Clear();
            SendErrorLog(RecordType.Info, "", "");
        }

        /** 
           * \brief 获取全部日志信息功能 
           */
        public static List<Record> GetLogRecord()
        {
            return systemLogRecords.recordList;
        }

        /**
         * \brief 将log数据转换为日志组合数据
         * 
         * \param[in] filePath log数据的路径
         */
        public static void ExportLog(string filePath)
        {
            bool result = true;
            //使用“另存为”对话框中输入的文件名实例化StreamWriter对象
            FileStream stream = new FileStream(filePath, FileMode.Create);
            try
            {
                //向创建的文件中写入内容
                using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
                {
                    writer.WriteLine(String.Format("日志时间：{0}", DateTime.Now.ToString()));
                    writer.WriteLine(string.Format("统计数据：{0}", AnalysisLogData(systemLogRecords.recordList)));
                    foreach (var v in systemLogRecords.recordList)
                    {
                        writer.WriteLine(v.SetRecordData());
                    }
                }
            }
            catch
            {
                result = false;
                SendErrorLog(RecordType.Warn, "日志数据导出失败", "");
                return;
            }
            if (result)
            {
                SendErrorLog(RecordType.Info, "日志数据导出成功", "");
            }
            //关闭当前文件写入流
            stream.Close();
        }

    }
}
